from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from datetime import timedelta
import requests
import json
from sqlalchemy.orm import load_only

from app.api.deps import get_db, get_current_active_user
from app.core.config import settings
from app.core.security import create_access_token
from app.crud.user import (
    get_user_by_email, 
    create_user, 
    verify_password, 
    update_last_login,
    create_or_update_wechat_user,
    get_user_by_openid
)
from app.models.user import User
from app.schemas.user import UserCreate, UserLogin, UserResponse, Token, WechatLogin
from app.schemas.response import success_response, error_response, ResponseCode

router = APIRouter()

def user_to_dict(user: User) -> dict:
    """将User模型转换为字典"""
    return {
        "id": user.id,
        "email": user.email,
        "nickname": user.nickname,
        "avatar": user.avatar,
        "gender": user.gender,
        "login_type": user.login_type,
        "status": user.status,
        "last_login_at": user.last_login_at,
        "created_at": user.created_at,
        "updated_at": user.updated_at
    }

@router.post("/register")
def register(user_in: UserCreate, db: Session = Depends(get_db)):
    """
    用户邮箱注册
    """
    # 检查邮箱是否已存在
    user = get_user_by_email(db, email=user_in.email)
    if user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="该邮箱已被注册"
        )
    
    # 创建新用户
    user = create_user(db, user_in)
    return success_response(data=user_to_dict(user), msg="注册成功")

@router.post("/login")
def login(
    form_data: OAuth2PasswordRequestForm = Depends(),
    db: Session = Depends(get_db)
):
    """
    邮箱登录获取token
    """
    user = get_user_by_email(db, email=form_data.username)
    if not user or not verify_password(form_data.password, user.password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="邮箱或密码错误",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    if user.status == 0:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="该账号已被禁用"
        )
    
    # 更新最后登录时间
    user = update_last_login(db, user)
    
    # 创建访问令牌
    access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        subject=user.id, expires_delta=access_token_expires
    )
    
    return success_response(
        data={
            "access_token": access_token,
            "token_type": "bearer",
            "user": user_to_dict(user)
        },
        msg="登录成功"
    )

@router.post("/login/email")
def login_email(
    login_data: UserLogin,
    db: Session = Depends(get_db)
):
    """
    邮箱登录API（非表单）
    """
    user = get_user_by_email(db, email=login_data.email)
    if not user or not verify_password(login_data.password, user.password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="邮箱或密码错误"
        )
    
    if user.status == 0:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="该账号已被禁用"
        )
    
    # 更新最后登录时间
    user = update_last_login(db, user)
    
    # 创建访问令牌
    access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        subject=user.id, expires_delta=access_token_expires
    )
    
    return success_response(
        data={
            "access_token": access_token,
            "token_type": "bearer",
            "user": user_to_dict(user)
        },
        msg="登录成功"
    )

@router.post("/login/wechat")
def login_wechat(
    wechat_data: WechatLogin,
    db: Session = Depends(get_db)
):
    """
    微信扫码登录
    """
    # 微信登录配置（实际使用时应从配置文件或环境变量获取）
    appid = "your_wechat_appid"  # 需要替换为实际的微信AppID
    secret = "your_wechat_secret"  # 需要替换为实际的微信AppSecret
    
    # 获取微信access_token
    url = f"https://api.weixin.qq.com/sns/oauth2/access_token?appid={appid}&secret={secret}&code={wechat_data.code}&grant_type=authorization_code"
    response = requests.get(url)
    result = json.loads(response.text)
    
    if "errcode" in result:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"微信登录失败: {result.get('errmsg', '未知错误')}"
        )
    
    access_token = result.get("access_token")
    openid = result.get("openid")
    unionid = result.get("unionid", "")  # 有些应用可能没有unionid
    
    # 获取用户信息
    user_info_url = f"https://api.weixin.qq.com/sns/userinfo?access_token={access_token}&openid={openid}&lang=zh_CN"
    user_response = requests.get(user_info_url)
    user_info = json.loads(user_response.text)
    
    if "errcode" in user_info:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"获取微信用户信息失败: {user_info.get('errmsg', '未知错误')}"
        )
    
    # 创建或更新用户
    user = create_or_update_wechat_user(
        db=db,
        unionid=unionid,
        openid=openid,
        nickname=user_info.get("nickname", ""),
        avatar=user_info.get("headimgurl", ""),
        gender=user_info.get("sex", 0)
    )
    
    # 创建访问令牌
    access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        subject=user.id, expires_delta=access_token_expires
    )
    
    return success_response(
        data={
            "access_token": access_token,
            "token_type": "bearer",
            "user": user_to_dict(user)
        },
        msg="微信登录成功"
    )

@router.post("/logout")
def logout(current_user: User = Depends(get_current_active_user)):
    """
    用户注销
    
    注意：由于JWT是无状态的，服务端无法真正"注销"令牌
    客户端应该删除本地存储的令牌
    """
    return success_response(msg="注销成功")

@router.get("/me")
def read_users_me(current_user: User = Depends(get_current_active_user)):
    """
    获取当前登录用户信息
    """
    return success_response(data=user_to_dict(current_user), msg="获取用户信息成功") 